/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.commons.configuration;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import junit.framework.TestCase;
/**
* Test class for HierarchicalINIConfiguration.
*
* @author <a
* href="http://commons.apache.org/configuration/team-list.html">Commons
* Configuration team</a>
* @version $Id: TestHierarchicalINIConfiguration.java 719869 2008-11-22 16:57:36Z oheger $
*/
public class TestHierarchicalINIConfiguration extends TestCase
{
private static String LINE_SEPARATOR = System.getProperty("line.separator");
/** Constant for the content of an ini file. */
private static final String INI_DATA = "[section1]" + LINE_SEPARATOR
+ "var1 = foo" + LINE_SEPARATOR + "var2 = 451" + LINE_SEPARATOR
+ LINE_SEPARATOR + "[section2]" + LINE_SEPARATOR + "var1 = 123.45"
+ LINE_SEPARATOR + "var2 = bar" + LINE_SEPARATOR + LINE_SEPARATOR
+ "[section3]" + LINE_SEPARATOR + "var1 = true" + LINE_SEPARATOR
+ "interpolated = ${section3.var1}" + LINE_SEPARATOR
+ "multi = foo" + LINE_SEPARATOR + "multi = bar" + LINE_SEPARATOR
+ LINE_SEPARATOR;
private static final String INI_DATA2 = "[section4]" + LINE_SEPARATOR
+ "var1 = \"quoted value\"" + LINE_SEPARATOR
+ "var2 = \"quoted value\\nwith \\\"quotes\\\"\"" + LINE_SEPARATOR
+ "var3 = 123 ; comment" + LINE_SEPARATOR
+ "var4 = \"1;2;3\" ; comment" + LINE_SEPARATOR
+ "var5 = '\\'quoted\\' \"value\"' ; comment" + LINE_SEPARATOR
+ "var6 = \"\"" + LINE_SEPARATOR;
private static final String INI_DATA3 = "[section5]" + LINE_SEPARATOR
+ "multiLine = one \\" + LINE_SEPARATOR
+ " two \\" + LINE_SEPARATOR
+ " three" + LINE_SEPARATOR
+ "singleLine = C:\\Temp\\" + LINE_SEPARATOR
+ "multiQuoted = one \\" + LINE_SEPARATOR
+ "\" two \" \\" + LINE_SEPARATOR
+ " three" + LINE_SEPARATOR
+ "multiComment = one \\ ; a comment" + LINE_SEPARATOR
+ "two" + LINE_SEPARATOR
+ "multiQuotedComment = \" one \" \\ ; comment" + LINE_SEPARATOR
+ "two" + LINE_SEPARATOR
+ "noFirstLine = \\" + LINE_SEPARATOR
+ " line 2" + LINE_SEPARATOR
+ "continueNoLine = one \\" + LINE_SEPARATOR;
/** An ini file with a global section. */
private static final String INI_DATA_GLOBAL = "globalVar = testGlobal"
+ LINE_SEPARATOR + LINE_SEPARATOR + INI_DATA;
/** A test ini file. */
private static final File TEST_FILE = new File("target/test.ini");
protected void tearDown() throws Exception
{
if (TEST_FILE.exists())
{
assertTrue("Cannot remove test file: " + TEST_FILE, TEST_FILE
.delete());
}
super.tearDown();
}
/**
* Creates a HierarchicalINIConfiguration object that is initialized from
* the given data.
*
* @param data the data of the configuration (an ini file as string)
* @return the initialized configuration
* @throws ConfigurationException if an error occurs
*/
private static HierarchicalINIConfiguration setUpConfig(String data)
throws ConfigurationException
{
StringReader reader = new StringReader(data);
HierarchicalINIConfiguration instance = new HierarchicalINIConfiguration();
instance.load(reader);
reader.close();
return instance;
}
/**
* Writes a test ini file.
*
* @param content the content of the file
* @throws IOException if an error occurs
*/
private static void writeTestFile(String content) throws IOException
{
PrintWriter out = new PrintWriter(new FileWriter(TEST_FILE));
try
{
out.println(content);
}
finally
{
out.close();
}
}
/**
* Test of save method, of class {@link HierarchicalINIConfiguration}.
*/
public void testSave() throws Exception
{
Writer writer = new StringWriter();
HierarchicalINIConfiguration instance = new HierarchicalINIConfiguration();
instance.addProperty("section1.var1", "foo");
instance.addProperty("section1.var2", "451");
instance.addProperty("section2.var1", "123.45");
instance.addProperty("section2.var2", "bar");
instance.addProperty("section3.var1", "true");
instance.addProperty("section3.interpolated", "${section3.var1}");
instance.addProperty("section3.multi", "foo");
instance.addProperty("section3.multi", "bar");
instance.save(writer);
assertEquals("Wrong content of ini file", INI_DATA, writer.toString());
}
/**
* Tests saving a configuration that contains a global section.
*/
public void testSaveWithGlobalSection() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
StringWriter writer = new StringWriter();
config.save(writer);
assertEquals("Wrong content of ini file", INI_DATA_GLOBAL, writer
.toString());
}
/**
* Test of load method, of class {@link HierarchicalINIConfiguration}.
*/
public void testLoad() throws Exception
{
checkLoad(INI_DATA);
}
/**
* Tests the load() method when the alternative value separator is used (a
* ':' for '=').
*/
public void testLoadAlternativeSeparator() throws Exception
{
checkLoad(INI_DATA.replace('=', ':'));
}
/**
* Tests loading a configuration from a File.
*/
public void testLoadFile() throws ConfigurationException, IOException
{
writeTestFile(INI_DATA);
HierarchicalINIConfiguration config = new HierarchicalINIConfiguration(
TEST_FILE);
checkContent(config);
}
/**
* Tests loading a configuration from a file name.
*/
public void testLoadFileName() throws ConfigurationException, IOException
{
writeTestFile(INI_DATA);
HierarchicalINIConfiguration config = new HierarchicalINIConfiguration(
TEST_FILE.getAbsolutePath());
checkContent(config);
}
/**
* Tests loading a configuration from a URL.
*/
public void testLoadURL() throws ConfigurationException, IOException
{
writeTestFile(INI_DATA);
HierarchicalINIConfiguration config = new HierarchicalINIConfiguration(
TEST_FILE.toURL());
checkContent(config);
}
/**
* Tests the values of some properties to ensure that the configuration was
* correctly loaded.
*
* @param instance the configuration to check
*/
private void checkContent(HierarchicalINIConfiguration instance)
{
assertTrue(instance.getString("section1.var1").equals("foo"));
assertTrue(instance.getInt("section1.var2") == 451);
assertTrue(instance.getDouble("section2.var1") == 123.45);
assertTrue(instance.getString("section2.var2").equals("bar"));
assertTrue(instance.getBoolean("section3.var1"));
assertTrue(instance.getSections().size() == 3);
}
/**
* Helper method for testing the load operation. Loads the specified content
* into a configuration and then checks some properties.
*
* @param data the data to load
*/
private void checkLoad(String data) throws ConfigurationException
{
HierarchicalINIConfiguration instance = setUpConfig(data);
checkContent(instance);
}
/**
* Test of isCommentLine method, of class
* {@link HierarchicalINIConfiguration}.
*/
public void testIsCommentLine()
{
HierarchicalINIConfiguration instance = new HierarchicalINIConfiguration();
assertTrue(instance.isCommentLine("#comment1"));
assertTrue(instance.isCommentLine(";comment1"));
assertFalse(instance.isCommentLine("nocomment=true"));
assertFalse(instance.isCommentLine(null));
}
/**
* Test of isSectionLine method, of class
* {@link HierarchicalINIConfiguration}.
*/
public void testIsSectionLine()
{
HierarchicalINIConfiguration instance = new HierarchicalINIConfiguration();
assertTrue(instance.isSectionLine("[section]"));
assertFalse(instance.isSectionLine("nosection=true"));
assertFalse(instance.isSectionLine(null));
}
/**
* Test of getSections method, of class {@link HierarchicalINIConfiguration}
* .
*/
public void testGetSections()
{
HierarchicalINIConfiguration instance = new HierarchicalINIConfiguration();
instance.addProperty("test1.foo", "bar");
instance.addProperty("test2.foo", "abc");
Set expResult = new HashSet();
expResult.add("test1");
expResult.add("test2");
Set result = instance.getSections();
assertEquals(expResult, result);
}
public void testQuotedValue() throws Exception
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA2);
assertEquals("value", "quoted value", config.getString("section4.var1"));
}
public void testQuotedValueWithQuotes() throws Exception
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA2);
assertEquals("value", "quoted value\\nwith \"quotes\"", config
.getString("section4.var2"));
}
public void testValueWithComment() throws Exception
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA2);
assertEquals("value", "123", config.getString("section4.var3"));
}
public void testQuotedValueWithComment() throws Exception
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA2);
assertEquals("value", "1;2;3", config.getString("section4.var4"));
}
public void testQuotedValueWithSingleQuotes() throws Exception
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA2);
assertEquals("value", "'quoted' \"value\"", config
.getString("section4.var5"));
}
public void testWriteValueWithCommentChar() throws Exception
{
HierarchicalINIConfiguration config = new HierarchicalINIConfiguration();
config.setProperty("section.key1", "1;2;3");
StringWriter writer = new StringWriter();
config.save(writer);
HierarchicalINIConfiguration config2 = new HierarchicalINIConfiguration();
config2.load(new StringReader(writer.toString()));
assertEquals("value", "1;2;3", config2.getString("section.key1"));
}
/**
* Tests whether whitespace is left unchanged for quoted values.
*/
public void testQuotedValueWithWhitespace() throws Exception
{
final String content = "CmdPrompt = \" [test@cmd ~]$ \"";
HierarchicalINIConfiguration config = setUpConfig(content);
assertEquals("Wrong propert value", " [test@cmd ~]$ ", config
.getString("CmdPrompt"));
}
/**
* Tests a quoted value with space and a comment.
*/
public void testQuotedValueWithWhitespaceAndComment() throws Exception
{
final String content = "CmdPrompt = \" [test@cmd ~]$ \" ; a comment";
HierarchicalINIConfiguration config = setUpConfig(content);
assertEquals("Wrong propert value", " [test@cmd ~]$ ", config
.getString("CmdPrompt"));
}
/**
* Tests an empty quoted value.
*/
public void testQuotedValueEmpty() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA2);
assertEquals("Wrong value for empty property", "", config
.getString("section4.var6"));
}
/**
* Tests a property that has no value.
*/
public void testGetPropertyNoValue() throws ConfigurationException
{
final String data = INI_DATA2 + LINE_SEPARATOR + "noValue ="
+ LINE_SEPARATOR;
HierarchicalINIConfiguration config = setUpConfig(data);
assertEquals("Wrong value of key", "", config
.getString("section4.noValue"));
}
/**
* Tests a property that has no key.
*/
public void testGetPropertyNoKey() throws ConfigurationException
{
final String data = INI_DATA2 + LINE_SEPARATOR + "= noKey"
+ LINE_SEPARATOR;
HierarchicalINIConfiguration config = setUpConfig(data);
assertEquals("Cannot find property with no key", "noKey", config
.getString("section4. "));
}
/**
* Tests reading a property from the global section.
*/
public void testGlobalProperty() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
assertEquals("Wrong value of global property", "testGlobal", config
.getString("globalVar"));
}
/**
* Tests whether the specified configuration contains exactly the expected
* sections.
*
* @param config the configuration to check
* @param expected an array with the expected sections
*/
private void checkSectionNames(HierarchicalINIConfiguration config,
String[] expected)
{
Set sectionNames = config.getSections();
Iterator it = sectionNames.iterator();
for (int idx = 0; idx < expected.length; idx++)
{
assertEquals("Wrong section at " + idx, expected[idx], it.next());
}
assertFalse("Too many sections", it.hasNext());
}
/**
* Tests the names of the sections returned by the configuration.
*
* @param data the data of the ini configuration
* @param expected the expected section names
* @return the configuration instance
*/
private HierarchicalINIConfiguration checkSectionNames(String data,
String[] expected) throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(data);
checkSectionNames(config, expected);
return config;
}
/**
* Tests querying the sections if a global section if available.
*/
public void testGetSectionsWithGlobal() throws ConfigurationException
{
checkSectionNames(INI_DATA_GLOBAL, new String[] {
null, "section1", "section2", "section3"
});
}
/**
* Tests querying the sections if there is no global section.
*/
public void testGetSectionsNoGlobal() throws ConfigurationException
{
checkSectionNames(INI_DATA, new String[] {
"section1", "section2", "section3"
});
}
/**
* Tests whether variables containing a dot are not misinterpreted as
* sections. This test is related to CONFIGURATION-327.
*/
public void testGetSectionsDottedVar() throws ConfigurationException
{
final String data = "dotted.var = 1" + LINE_SEPARATOR + INI_DATA_GLOBAL;
HierarchicalINIConfiguration config = checkSectionNames(data,
new String[] {
null, "section1", "section2", "section3"
});
assertEquals("Wrong value of dotted variable", 1, config
.getInt("dotted..var"));
}
/**
* Tests whether a section added later is also found by getSections().
*/
public void testGetSectionsAdded() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA2);
config.addProperty("section5.test", Boolean.TRUE);
checkSectionNames(config, new String[] {
"section4", "section5"
});
}
/**
* Tests querying the properties of an existing section.
*/
public void testGetSectionExisting() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA);
SubnodeConfiguration section = config.getSection("section1");
assertEquals("Wrong value of var1", "foo", section.getString("var1"));
assertEquals("Wrong value of var2", "451", section.getString("var2"));
}
/**
* Tests querying the properties of a section that was merged from two
* sections with the same name.
*/
public void testGetSectionMerged() throws ConfigurationException
{
final String data = INI_DATA + "[section1]" + LINE_SEPARATOR
+ "var3 = merged" + LINE_SEPARATOR;
HierarchicalINIConfiguration config = setUpConfig(data);
SubnodeConfiguration section = config.getSection("section1");
assertEquals("Wrong value of var1", "foo", section.getString("var1"));
assertEquals("Wrong value of var2", "451", section.getString("var2"));
assertEquals("Wrong value of var3", "merged", section.getString("var3"));
}
/**
* Tests querying the content of the global section.
*/
public void testGetSectionGlobal() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
SubnodeConfiguration section = config.getSection(null);
assertEquals("Wrong value of global variable", "testGlobal", section
.getString("globalVar"));
}
/**
* Tests querying the content of the global section if there is none.
*/
public void testGetSectionGlobalNonExisting() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA);
SubnodeConfiguration section = config.getSection(null);
assertTrue("Sub config not empty", section.isEmpty());
}
/**
* Tests querying a non existing section.
*/
public void testGetSectionNonExisting() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA);
SubnodeConfiguration section = config
.getSection("Non existing section");
assertTrue("Sub config not empty", section.isEmpty());
}
/**
* Tests a property whose value spans multiple lines.
*/
public void testLineContinuation() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA3);
assertEquals("Wrong value", "one" + LINE_SEPARATOR + "two"
+ LINE_SEPARATOR + "three", config
.getString("section5.multiLine"));
}
/**
* Tests a property value that ends on a backslash, which is no line
* continuation character.
*/
public void testLineContinuationNone() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA3);
assertEquals("Wrong value", "C:\\Temp\\", config
.getString("section5.singleLine"));
}
/**
* Tests a property whose value spans multiple lines when quoting is
* involved. In this case whitespace must not be trimmed.
*/
public void testLineContinuationQuoted() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA3);
assertEquals("Wrong value", "one" + LINE_SEPARATOR + " two "
+ LINE_SEPARATOR + "three", config
.getString("section5.multiQuoted"));
}
/**
* Tests a property whose value spans multiple lines with a comment.
*/
public void testLineContinuationComment() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA3);
assertEquals("Wrong value", "one" + LINE_SEPARATOR + "two", config
.getString("section5.multiComment"));
}
/**
* Tests a property with a quoted value spanning multiple lines and a
* comment.
*/
public void testLineContinuationQuotedComment()
throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA3);
assertEquals("Wrong value", " one " + LINE_SEPARATOR + "two", config
.getString("section5.multiQuotedComment"));
}
/**
* Tests a multi-line property value with an empty line.
*/
public void testLineContinuationEmptyLine() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA3);
assertEquals("Wrong value", LINE_SEPARATOR + "line 2", config
.getString("section5.noFirstLine"));
}
/**
* Tests a line continuation at the end of the file.
*/
public void testLineContinuationAtEnd() throws ConfigurationException
{
HierarchicalINIConfiguration config = setUpConfig(INI_DATA3);
assertEquals("Wrong value", "one" + LINE_SEPARATOR, config
.getString("section5.continueNoLine"));
}
}